package org.example.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.example.common.Constants;
import org.example.common.R;
import org.example.pojo.entity.SysUser;
import org.example.pojo.req.SysUserReq;
import org.example.pojo.vo.UserVo;
import org.example.service.SysUserRoleService;
import org.example.service.SysUserService;
import org.example.utils.AliOssUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.awt.*;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static org.example.utils.securityContextUserInfo.getContextUserInfo;

@Api(value = "/api/user", tags = {"}"})
@RestController
@RequestMapping("/api/user")
@Slf4j
public class SysUserController {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysUserRoleService sysUserRoleService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private AliOssUtil aliOssUtil;


    /**
     * 生成图片校验码
     *
     * @return
     */
    @ApiOperation(value = "生成图片校验码", notes = "生成图片校验码", httpMethod = "GET")
    @GetMapping("/captcha")
    public R captchaCode() {
        //参数分别是宽、高、验证码长度、干扰线数量
        LineCaptcha captcha = CaptchaUtil.createLineCaptcha(250, 40, 4, 5);
        //设置背景颜色清灰
        captcha.setBackground(Color.lightGray);
        //获取图片中的验证码，默认生成的校验码包含文字和数字，长度为4
        String checkCode = captcha.getCode();
        log.info("生成校验码:{}", checkCode);
        //生成sessionId
        String sessionId = String.valueOf(IdWorker.getId());
        //将sessionId和校验码保存在redis下，并设置缓存中数据存活时间一分钟
        redisTemplate.opsForValue().set(Constants.CHECK_CODE + sessionId, checkCode, 60, TimeUnit.MINUTES);
        //组装响应数据
        HashMap<String, String> info = new HashMap<>();
        info.put("sessionId", sessionId);
        info.put("imageData", captcha.getImageBase64());//获取base64格式的图片数据
        //设置响应数据格式
        return R.ok(info);
    }

    /**
     * 登录
     *
     * @return
     */
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "body", dataType = "SysUser", name = "sysUser", value = "", required = true)
    })
    @ApiOperation(value = "登录", notes = "登录", httpMethod = "POST")
    @PostMapping("/login")
    public R getUserList(@RequestBody SysUser sysUser) {
        return sysUserService.login(sysUser);
    }

    /**
     * 分页获取用户数据列表
     *
     * @param page
     * @param size
     * @param userName
     * @param phonenumber
     * @param status
     * @param startTime
     * @param endTime
     * @return
     */
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", dataType = "int", name = "page", value = ""),
            @ApiImplicitParam(paramType = "path", dataType = "int", name = "size", value = ""),
            @ApiImplicitParam(paramType = "query", dataType = "string", name = "userName", value = ""),
            @ApiImplicitParam(paramType = "query", dataType = "string", name = "phonenumber", value = ""),
            @ApiImplicitParam(paramType = "query", dataType = "string", name = "status", value = ""),
            @ApiImplicitParam(paramType = "query", dataType = "string", name = "startTime", value = ""),
            @ApiImplicitParam(paramType = "query", dataType = "string", name = "endTime", value = "")
    })
    @ApiOperation(value = "分页获取用户数据", notes = "分页获取用户数据", httpMethod = "GET")
    @GetMapping("/list/{page}/{size}")
    public R getUserList(@PathVariable(required = false) Integer page,
                         @PathVariable(required = false) Integer size,
                         @RequestParam(required = false) String userName,
                         @RequestParam(required = false) String phonenumber,
                         @RequestParam(required = false) String status,
                         @RequestParam(required = false) String startTime,
                         @RequestParam(required = false) String endTime
    ) {
        Page<UserVo> sysUserPage = sysUserService.pageList(page, size, userName, phonenumber, status, startTime, endTime);

        return R.ok(sysUserPage);
    }


    /**
     * 获取用户信息
     *
     * @param userId
     * @return
     */
    @GetMapping("/{userId}")
    public R getDetail(@PathVariable String userId) {
        return sysUserService.getUserDetail(userId);
    }

    /**
     * 添加用户
     *
     * @param userReq
     * @return
     */
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "body", dataType = "SysUserReq", name = "userReq", value = "", required = true)
    })
    @ApiOperation(value = "添加用户", notes = "添加用户", httpMethod = "POST")
    @PostMapping("/add")
    public R addUser(@RequestBody SysUserReq userReq) {
        return sysUserService.saveUser(userReq);

    }

    /**
     * 修改用户信息
     *
     * @param userReq
     * @return
     */
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "body", dataType = "SysUserReq", name = "userReq", value = "", required = true)
    })
    @ApiOperation(value = "修改用户信息", notes = "修改用户信息", httpMethod = "PUT")
    @PutMapping("/edit")
    public R editUser(@RequestBody SysUserReq userReq) {
        return sysUserService.editUser(userReq);
    }

    /**
     * 删除用户
     *
     * @param id
     * @return
     */
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", dataType = "string", name = "id", value = "", required = true)
    })
    @ApiOperation(value = "删除用户", notes = "删除用户", httpMethod = "DELETE")
    @DeleteMapping("/remove/{id}")
    public R removeUser(@PathVariable String id) {
        sysUserService.removeUser(id);
        return R.ok("操作成功");
    }

    /**
     * 用户管理重置密码
     *
     * @param userId
     * @return
     */
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", dataType = "string", name = "userId", value = "", required = true),
    })
    @ApiOperation(value = "重置密码", notes = "重置密码", httpMethod = "PUT")
    @PutMapping("/reset/{userId}")
    public R resetPasswordManage(@PathVariable String userId) {
        SysUser sysUser = sysUserService.getById(userId);
        sysUser.setPassword(passwordEncoder.encode("123456"));
        sysUserService.updateById(sysUser);
        return R.ok("重置密码成功");
    }

    /**
     * 禁用/启用用户
     *
     * @param userId
     * @param status
     * @return
     */
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", dataType = "string", name = "userId", value = "", required = true),
            @ApiImplicitParam(paramType = "path", dataType = "string", name = "status", value = "", required = true)
    })
    @ApiOperation(value = "禁用/启用用户", notes = "禁用/启用用户", httpMethod = "PUT")
    @PutMapping("/suspend/{userId}/{status}")
    public R suspendUser(@PathVariable String userId, @PathVariable String status) {
        SysUser sysUser = sysUserService.getById(userId);
        sysUser.setStatus(status);
        sysUserService.updateById(sysUser);
        return R.ok(null);
    }

    /**
     * 个人中心用户信息
     *
     * @return
     */
    @ApiOperation(value = "个人中心用户信息", notes = "个人中心用户信息", httpMethod = "GET")
    @GetMapping("/info")
    public R getUserInfo() {
        return sysUserService.getUserInfos();
    }

    /**
     * 个人中心用户基本信息修改
     *
     * @return
     */
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "body", dataType = "SysUser", name = "sysUser", value = "", required = true)
    })
    @ApiOperation(value = "个人中心用户基本信息修改", notes = "个人中心用户基本信息修改", httpMethod = "PUT")
    @PutMapping("/info")
    public R editUserInfo(@RequestBody SysUser sysUser) {
        sysUserService.editUserInfo(sysUser);
        return R.ok(null);
    }

    /**
     * 个人中心修改密码
     *
     * @param oldPassword
     * @param newPassword
     * @return
     */
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", dataType = "string", name = "oldPassword", value = "", required = true),
            @ApiImplicitParam(paramType = "path", dataType = "string", name = "newPassword", value = "", required = true)
    })
    @ApiOperation(value = "个人中心修改密码", notes = "个人中心修改密码", httpMethod = "PUT")
    @PutMapping("reset/password/{oldPassword}/{newPassword}")
    public R resetPassword(@PathVariable String oldPassword, @PathVariable String newPassword) {
        return sysUserService.resetPassword(oldPassword, newPassword);
    }

    /**
     * 上传个人信息图片
     *
     * @param file
     * @return
     */
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "form", dataType = "file", name = "file", value = "", required = true)
    })
    @ApiOperation(value = "上传个人信息图片", notes = "上传个人信息图片", httpMethod = "POST")
    @PostMapping("/upload")
    public R uploadFile(@RequestParam MultipartFile file) throws IOException {
        String url = aliOssUtil.upload(file.getOriginalFilename(), file.getInputStream());
        sysUserService.editUserInfoFile(getContextUserInfo(), url);
        return R.ok(null);
    }

    /**
     * 批量删除用户信息
     *
     * @param ids
     * @return
     */
    @DeleteMapping("/batch")
    public R deleteBatch(@RequestBody String[] ids) {
        sysUserService.removeBatchByIds(Arrays.asList(ids));
        return R.ok("删除成功");
    }
}
